今天的實戰項目是一個運勢占卜 App,使用者可以選擇一個問題進行占卜,App 會根據隨機的 Yes/No 回應,並搭配圖片結果來展示占卜結果。
本次開發將進一步拓展,從之前操作本地端資料切換到網路讀取資料,透過 API 連接來實現占卜問題與結果的獲取。我們會使用 URLSession 抓取後台的 JSON 資料,並利用第三方庫 Kingfisher 來處理並顯示圖片。這個練習不僅讓你熟悉 API 串接與 JSON 資料解析,還能學習如何高效處理網路圖片加載。
這個運勢占卜 App 可幫助使用者提出一個問題,並從 API 得到「Yes」或「No」的答案,附帶有趣的 GIF 圖片作為結果展示。
操作動畫:
螢幕截圖:
流程蠻簡易的!
在 Storyboard 中,我們會使用以下 UI 元件:
首先,我們會建立一個簡單的 JSON 文件,放置在 GitHub 中,內容是預設的一些占卜問題,並用 URLSession 來抓取這些問題。這些問題將顯示在 UIPickerView 中,讓使用者進行選擇。
從 github 讀取自定義 JSON API,取得占卜題目
https://raw.githubusercontent.com/JasonHungApp/JSON_API/main/YesOrNoQuestion
Sample JSON:
[
"我的運勢好嗎?",
"最近愛情運好嗎?",
"今天財運如何?",
"尾牙會中大獎嗎?",
"今天要買股票嗎?",
"考試會順利嗎?"
]
抓取問題的程式碼:
let yesOrNoQuestionURL = URL(string: "https://raw.githubusercontent.com/YourGitHubAccount/JSON_API/main/YesOrNoQuestion")!
func fetchYesOrNoQuestion(completion: @escaping ([String]) -> Void) {
let jsonURL = yesOrNoQuestionURL
fetchData(from: jsonURL) { data in
guard let data else {
print("未獲得有效的 JSON 數據")
return
}
do {
let decodedData = try JSONDecoder().decode([String].self, from: data)
completion(decodedData)
} catch {
print("解碼 JSON 時發生錯誤:", error.localizedDescription)
completion([])
}
}
}
運行結果:
當使用者選定問題並點擊按鈕開始占卜時,App 會發送請求到 yesno.wtf API,隨機返回「YES」或「NO」以及一個對應的 GIF 圖片 URL。
API 回應範例:
{
"answer": "yes",
"forced": false,
"image": "https://yesno.wtf/assets/yes/2.gif"
}
抓取占卜結果的程式碼:
func fetchYesNoData(completion: @escaping (Result<YesNoResponse, Error>) -> Void) {
let jsonURL = URL(string: "https://yesno.wtf/api")!
fetchData(from: jsonURL) { data in
guard let data = data else {
print("未獲得有效的 JSON 數據")
completion(.failure(NSError(domain: "com.example", code: -1, userInfo: [NSLocalizedDescriptionKey: "未獲得有效的 JSON 數據"])))
return
}
do {
let decodedData = try JSONDecoder().decode(YesNoResponse.self, from: data)
completion(.success(decodedData))
} catch {
print("解碼 JSON 時發生錯誤:", error.localizedDescription)
completion(.failure(error))
}
}
}
為了能夠在運勢占卜 App 中處理並加載網路圖片,我們將使用第三方庫 Kingfisher。這是一個專門為 Swift 設計的圖片下載與快取工具,使用非常簡單,並能優化圖片加載的效能。
開啟 Xcode,並選擇你的專案。
點擊左上角的「File」選單,選擇 Add Packages。
在彈出的視窗中,輸入 Kingfisher 的 GitHub 位址:
https://github.com/onevcat/Kingfisher.git
Kingfisher 是一個專門處理圖片加載的第三方框架,能夠有效管理圖片的下載和緩存。當我們取得 API 回應中的圖片 URL 後,會使用 Kingfisher 來加載圖片。
使用 Kingfisher 加載圖片:
self.imageView.kf.setImage(with: URL(string: yesNoResponse.image), completionHandler: { result in
switch result {
case .success(_):
DispatchQueue.main.async {
self.activityIndicator.stopAnimating() // 停止指示器
self.yesNoText = yesNoResponse.answer
self.showResultVC() // 顯示結果
}
case .failure(let error):
print("載入圖片失敗:", error.localizedDescription)
}
})
當占卜結果取得後,會將結果顯示在新的一個 resultViewController 中,內容包含使用者選擇的占卜問題、占卜結果(YES/NO)以及對應的 gif 圖片。
傳遞資料到結果畫面:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "resultSegueIdentifier" {
if let resultVC = segue.destination as? resultViewController {
let selectedRow = questionPickerView.selectedRow(inComponent: 0)
resultVC.question = questions[selectedRow]
resultVC.yesNoText = yesNoText.uppercased()
resultVC.image = imageView.image!
}
}
}
這樣我們就完成了一個運勢占卜 App!這個專案不僅教你如何串接 API,還展示了如何使用 Kingfisher 進行圖片加載,讓 App 更加生動有趣。
在這篇教學中,我們開發了一個簡單的運勢占卜 App,過程中我們學習了以下幾個重要的 iOS 開發技巧:
透過這些技術的結合,我們打造了一個有趣且實用的占卜 App,讓使用者能夠體驗到即時的運勢占卜過程。接下來,你可以進一步思考如何擴展這個 App,例如加入更多的 API、增加不同類型的占卜選項,或者設計更豐富的結果呈現方式,讓 App 的功能更加全面!